package com.sz.ac.utils.excel;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import com.sz.ac.entity.AcInvest;
import com.sz.ac.model.constant.DefMsgException;

import java.io.*;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class ImportExcel {
	private static final Logger logger = LoggerFactory.getLogger(ImportExcel.class);
	//标题
	private String[] title = {"投资人手机号","投资金额","投资时间"};
	// 总行数
	private int totalRows = 0;
	// 总条数
	private int totalCells = 0;
	// 错误信息接收器
	private String errorMsg;

	// 构造方法
	public ImportExcel() {
	}

	// 获取总行数
	public int getTotalRows() {
		return totalRows;
	}

	// 获取总列数
	public int getTotalCells() {
		return totalCells;
	}

	// 获取错误信息
	public String getErrorInfo() {
		return errorMsg;
	}

	/**
	 * 验证EXCEL文件
	 * 
	 * @param filePath
	 * @return
	 */
	public boolean validateExcel(String filePath) {
		if (filePath == null || !(WDWUtil.isExcel2003(filePath) || WDWUtil.isExcel2007(filePath))) {
			errorMsg = "文件名不是excel格式";
			return false;
		}
		return true;
	}

	/**
	 * 读EXCEL文件，获取客户信息集合
	 * 
	 * @param
	 * @return
	 */
	public List<AcInvest> getExcelInfo(String fileName, MultipartFile Mfile) {

		// 把spring文件上传的MultipartFile转换成CommonsMultipartFile类型
		CommonsMultipartFile cf = (CommonsMultipartFile) Mfile; // 获取本地存储路径
		File file = new File("D:\\fileupload");
		// 创建一个目录 （它的路径名由当前 File 对象指定，包括任一必须的父路径。）
		if (!file.exists())
			file.mkdirs();
		// 新建一个文件
		File file1 = new File("D:\\fileupload" + new Date().getTime() + ".xlsx");
		// 将上传的文件写入新建的文件中
		try {
			cf.getFileItem().write(file1);
		} catch (Exception e) {
			e.printStackTrace();
		}

		// 初始化客户信息的集合
		List<AcInvest> customerList = new ArrayList<AcInvest>();
		// 初始化输入流
		InputStream is = null;
		try {
			// 验证文件名是否合格
			if (!validateExcel(fileName)) {
				return null;
			}
			// 根据文件名判断文件是2003版本还是2007版本
			boolean isExcel2003 = true;
			if (WDWUtil.isExcel2007(fileName)) {
				isExcel2003 = false;
			}
			// 根据新建的文件实例化输入流
			is = new FileInputStream(file1);
			// 根据excel里面的内容读取客户信息
			customerList = getExcelInfo(is, isExcel2003);
			is.close();
		} catch (Exception e) {
			logger.error("======ex:{}==", e);
		} finally {
			if (is != null) {
				try {
					is.close();
				} catch (IOException e) {
					is = null;
					e.printStackTrace();
				}
			}
		}
		return customerList;
	}

	/**
	 * 读EXCEL文件，获取客户信息集合
	 * 
	 * @param
	 * @return
	 * @throws IOException 
	 */
	public List<AcInvest> importExcel(String fileName, MultipartFile multiFile) throws IOException {

		// 初始化客户信息的集合
		List<AcInvest> customerList = new ArrayList<AcInvest>();
		// 初始化输入流
		InputStream is = null;
		try 
		{
			// 验证文件名是否合格
			if (!validateExcel(fileName)) {
				return null;
			}
			// 根据文件名判断文件是2003版本还是2007版本
			boolean isExcel2003 = true;
			if (WDWUtil.isExcel2007(fileName)) {
				isExcel2003 = false;
			}
			is = multiFile.getInputStream();
			// 根据excel里面的内容读取客户信息
			customerList = getExcelInfo(is, isExcel2003);
			is.close();
		} finally {
			if (is != null) {
				try {
					is.close();
				} catch (IOException e) {
					is = null;
					e.printStackTrace();
				}
			}
		}
		return customerList;
	}

	/**
	 * 根据excel里面的内容读取客户信息
	 * 
	 * @param is
	 *            输入流
	 * @param isExcel2003
	 *            excel是2003还是2007版本
	 * @return
	 * @throws IOException
	 */
	public List<AcInvest> getExcelInfo(InputStream is, boolean isExcel2003) throws IOException {
		List<AcInvest> customerList = null;
		/** 根据版本选择创建Workbook的方式 */
		Workbook wb = null;
		// 当excel是2003时
		if (isExcel2003) {
			wb = new HSSFWorkbook(is);
		} else {// 当excel是2007时
			wb = new XSSFWorkbook(is);
		}
		// 读取Excel里面客户的信息
		customerList = readExcelValue(wb);
		return customerList;
	}

	/**
	 * 读取Excel里面客户的信息
	 * 
	 * @param wb
	 * @return
	 */
	private List<AcInvest> readExcelValue(Workbook wb) {
		// 得到第一个shell
		Sheet sheet = wb.getSheetAt(0);

		// 得到Excel的行数
		this.totalRows = sheet.getPhysicalNumberOfRows();

		// 得到Excel的列数(前提是有行数)
		if (totalRows >= 1 && sheet.getRow(0) != null) {
			this.totalCells = sheet.getRow(0).getPhysicalNumberOfCells();
		}
		//标题判断
		Row titleRow = sheet.getRow(0);
		for(int i=0;i<title.length;i++){
			Cell cell = titleRow.getCell(i);
			if(cell != null ){
				cell.setCellType(Cell.CELL_TYPE_STRING);
				if(!title[i].equals(cell.getStringCellValue())){
					throw new DefMsgException("导入的数据模板标题不正确，请下载模板并按照格式导入");
				}
			}else{
				logger.error("=====cell i={}",i);
				throw new DefMsgException("导入的数据模板标题不正确，请下载模板并按照格式导入");
			}
			
		}
		
		
		List<AcInvest> AcInvestList = new ArrayList<AcInvest>();
		List<String> phoneList = new ArrayList<String>();
		// 循环Excel行数,从第二行开始。标题不入库
		for (int r = 1; r < totalRows; r++) {
			Row row = sheet.getRow(r);
			if (row == null || row.getCell(0)==null)
				continue;
			AcInvest acInvest = new AcInvest();
			// 循环Excel的列
			for (int c = 0; c < this.totalCells; c++) {
				Cell cell = row.getCell(c);
				if (null != cell) {
					acInvest.setTsp(new Date());
					if (c == 0) {
						cell.setCellType(Cell.CELL_TYPE_STRING);
						String phone = cell.getStringCellValue();
						acInvest.setPhone(phone);
						if(phoneList.contains(phone)){
							throw new DefMsgException("存在重复的手机号");
						}
					} else if (c == 1) {
						cell.setCellType(Cell.CELL_TYPE_STRING);
						acInvest.setAmount(new BigDecimal(cell.getStringCellValue()));
					} else if (c == 2) {
						logger.info("date_type={},,val={}========",cell.getCellType(),cell.getNumericCellValue());
						acInvest.setInvestTime(cell.getDateCellValue());
					} 
				}
				
			}
			AcInvestList.add(acInvest);
		}
		return AcInvestList;
	}
}
